Managing Android and iOS Project Configurations
Course: React Native Training
Topic: Managing Android and iOS Project Configurations
Course Link: React Native Training at JustAcademy
Demo Link: Register for a Course Demo
JustAcademy Website: Visit JustAcademy
1. Introduction to Android and iOS Project Configurations
React Native allows developers to build applications for Android and iOS using JavaScript or TypeScript and React. Although much of the application logic can be shared, each platform has its own native project structure, build system, application identifiers, permissions, signing requirements, environment settings, and release process.
Managing Android and iOS project configurations means maintaining the settings required to build, run, test, and distribute an application correctly on both platforms. A well-configured project helps developers avoid build failures, permission errors, inconsistent application behavior, and problems during store submission.
Android configuration primarily uses Gradle, Android manifests, Kotlin or Java source files, and Android Studio. iOS configuration primarily uses Xcode, project and workspace files, build settings, Info.plist or equivalent configuration, entitlements, and CocoaPods where applicable.
React Native developers should understand both native environments because a shared JavaScript codebase still depends on platform-specific configuration for many device capabilities and deployment requirements.
1.1 Learning Objectives
- Understand the differences between Android and iOS project structures.
- Identify important React Native native configuration files.
- Manage application names, identifiers, version numbers, and build settings.
- Configure development, testing, staging, and production environments.
- Understand Android Gradle configuration and iOS Xcode configuration.
- Manage platform permissions and application capabilities.
- Understand native dependencies and package installation.
- Configure development and release builds.
- Understand signing, credentials, and application distribution.
- Debug common Android and iOS configuration problems.
- Apply configuration management and security best practices.
1.2 Prerequisites
- Basic JavaScript or TypeScript knowledge.
- Understanding of React Native components and application structure.
- Basic command-line knowledge.
- Node.js and a compatible package manager installed.
- Android Studio and Android SDK for Android development.
- A Mac with Xcode installed for the standard native iOS build workflow.
- Basic familiarity with Git and environment variables.
2. Understanding the React Native Project Structure
A React Native project contains JavaScript or TypeScript application code alongside native platform projects. The JavaScript portion contains shared application logic, while the Android and iOS folders contain configuration and native code specific to each platform.
2.1 Common Project Files and Folders
| File or Folder |
Purpose |
src/ |
Often contains application screens, components, hooks, and business logic. |
android/ |
Contains the native Android project and related configuration. |
ios/ |
Contains the native iOS project and related configuration. |
package.json |
Defines JavaScript dependencies and project scripts. |
package-lock.json |
Records resolved dependency versions when npm is used. |
yarn.lock |
Records resolved dependency versions when Yarn is used. |
app.json |
Contains basic project metadata and may contain app configuration for supported tooling. |
app.config.js or app.config.ts |
Can provide dynamic configuration in Expo projects. |
babel.config.js |
Configures Babel, the JavaScript transformation tool. |
metro.config.js |
Configures Metro, the JavaScript bundler used by React Native. |
react-native.config.js |
Supports certain React Native CLI and dependency configuration options. |
.gitignore |
Defines files and folders Git should ignore. |
.env files |
May store environment-specific configuration values when a suitable loading method is configured. |
Not every project contains all these files. Bare React Native projects and Expo projects may use different configuration workflows, and file structures vary across React Native versions and templates.
2.2 Typical Android Project Structure
MyReactNativeApp/
├── android/
│ ├── app/
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ └── res/
│ ├── build.gradle
│ ├── gradle.properties
│ ├── settings.gradle
│ └── gradlew
├── ios/
├── src/
├── package.json
└── app.json
This is a simplified example. Newer templates may use Kotlin Gradle scripts, different source directories, or other project organization conventions.
2.3 Typical iOS Project Structure
MyReactNativeApp/
├── ios/
│ ├── MyReactNativeApp.xcodeproj/
│ ├── MyReactNativeApp.xcworkspace
│ ├── Podfile
│ ├── Podfile.lock
│ └── MyReactNativeApp/
│ ├── AppDelegate.swift
│ ├── Info.plist
│ └── Images.xcassets/
├── android/
├── src/
└── package.json
Some files shown here are optional or template-dependent. In particular, an Xcode workspace is commonly used when CocoaPods dependencies are installed. Follow the structure of the project you are actually working on.
3. Android and iOS Configuration Differences
Android and iOS provide similar user-facing features but use different tools and configuration mechanisms. Developers should learn each platform's conventions rather than trying to manage every setting through one generic file.
| Configuration Area |
Android |
iOS |
| Primary native IDE |
Android Studio |
Xcode |
| Build system |
Gradle |
Xcode build system |
| Main build configuration |
android/app/build.gradle or build.gradle.kts |
Xcode project settings and build configurations |
| Application identifier |
applicationId |
Bundle identifier |
| Manifest or metadata |
AndroidManifest.xml |
Info.plist and other target settings |
| Minimum supported OS |
Android minimum SDK configuration |
iOS deployment target |
| Build variants |
Build types and product flavors |
Build configurations and schemes |
| Signing |
Keystore and signing configuration |
Certificates, provisioning profiles, and signing settings |
| Dependency management |
Gradle dependencies and Android tooling |
CocoaPods, Swift Package Manager, and Xcode project references as appropriate |
| Release output |
APK or Android App Bundle (AAB) |
Archived application for distribution, commonly submitted through App Store Connect |
4. Managing Application Names and Identifiers
An application name is the human-readable label shown to users. An application identifier is a technical identifier used by the platform and distribution ecosystem. These values serve different purposes and should be configured carefully.
4.1 Android Application Name
Android commonly uses a string resource for the application label.
<!-- android/app/src/main/res/values/strings.xml -->
<resources>
<string name="app_name">My React Native App</string>
</resources>
The application label may reference this resource from the Android manifest:
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:allowBackup="false"
android:theme="@style/AppTheme">
</application>
The exact attributes in the manifest depend on the application template and its requirements. Preserve existing required entries when editing this file.
4.2 Android Application ID
The Android application ID uniquely identifies an application for installation and distribution. It is normally configured in the app-level Gradle file.
android {
namespace "com.example.myapp"
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 24
targetSdkVersion 35
versionCode 1
versionName "1.0"
}
}
This is an illustrative Groovy Gradle configuration. SDK values should match the supported versions and requirements of the project's current React Native release and dependencies. Do not copy example SDK numbers without checking compatibility.
The namespace and applicationId have related but distinct purposes. The namespace determines the namespace used by generated classes and certain source declarations, while the application ID identifies the installed application. Existing projects may need these values to remain different.
4.3 iOS Display Name
The display name is commonly configured through the CFBundleDisplayName property in Info.plist or through the corresponding Xcode build settings.
<key>CFBundleDisplayName</key>
<string>My React Native App</string>
When the value is configured through Xcode build settings or generated configuration, avoid maintaining conflicting values in multiple locations.
4.4 iOS Bundle Identifier
The bundle identifier identifies the iOS application in Xcode and Apple's distribution ecosystem. It commonly uses reverse-domain notation.
com.example.myapp
In Xcode, select the appropriate project target and review the Signing & Capabilities section. Confirm that the bundle identifier matches the intended app record, signing team, and distribution configuration.
4.5 Naming Best Practices
- Use clear and consistent naming conventions.
- Keep the Android application ID and iOS bundle identifier documented.
- Use unique identifiers for separate applications or distribution variants where appropriate.
- Check all native references before changing an established identifier.
- Verify deep links, push notifications, OAuth redirect settings, and service configurations after renaming.
- Remember that changing an identifier may cause the platform to treat the application as a different app for installation or distribution purposes.
5. Managing Version Numbers and Build Numbers
Applications use version information to communicate releases to users and to control update behavior. Android and iOS have different version fields, so each platform must be configured correctly.
5.1 Android Version Configuration
android {
defaultConfig {
versionCode 12
versionName "1.2.0"
}
}
- versionCode: An integer used by Android and app distribution services to identify release progression.
- versionName: A user-facing version string, such as 1.2.0.
Increase the version code when preparing a new store release, following the distribution service's current rules. Ensure that it remains within the supported limits for the chosen toolchain.
5.2 iOS Version Configuration
iOS commonly uses two build settings:
- Version: The marketing version, commonly represented by
CFBundleShortVersionString.
- Build: The build number, commonly represented by
CFBundleVersion.
These values are normally managed through Xcode's target settings or through the corresponding Info.plist substitutions.
| Platform |
Version Field |
Example |
| Android |
versionName |
1.2.0 |
| Android |
versionCode |
12 |
| iOS |
CFBundleShortVersionString |
1.2.0 |
| iOS |
CFBundleVersion |
12 |
5.3 Versioning Best Practices
- Use a consistent versioning strategy across the team.
- Increment platform build numbers for new distribution builds as required.
- Keep the user-facing version and internal build number separate.
- Verify version values before creating a release artifact.
- Document any differences between Android and iOS release numbering.
6. Configuring Android Build Settings with Gradle
Gradle is the build automation system used by Android projects. React Native Android builds use Gradle configuration to define application identifiers, SDK requirements, build variants, dependencies, signing, and other native build behavior.
6.1 Root-Level and App-Level Gradle Files
| File |
Purpose |
android/build.gradle |
Contains project-level build configuration in projects using Groovy Gradle scripts. |
android/build.gradle.kts |
Kotlin DSL alternative for project-level build configuration. |
android/app/build.gradle |
Common location for app-specific settings and build types. |
android/app/build.gradle.kts |
Kotlin DSL alternative for app-specific configuration. |
android/gradle.properties |
Contains project-level Gradle properties. |
android/settings.gradle |
Defines project structure and plugin or dependency inclusion in applicable setups. |
android/gradle/wrapper/ |
Contains Gradle Wrapper configuration for consistent builds. |
Always check whether the project uses Groovy or Kotlin DSL. The syntax differs, and configuration from one format should not be pasted directly into the other.
6.2 Understanding Build Types
Android build types usually include debug and release configurations. The debug type is used for development and debugging, while release is configured for distribution and production behavior.
android {
buildTypes {
debug {
// Development-specific settings
}
release {
minifyEnabled false
// Add project-specific release settings here
}
}
}
This is a simplified example. Keep the build settings generated by the project's template unless a change is required and understood. Release optimization, resource shrinking, and native library rules should be tested carefully before enabling them.
6.3 Product Flavors
Product flavors let Android projects define variants for different environments, customer editions, or distribution channels. For example, an application may have development, staging, and production variants.
android {
flavorDimensions "environment"
productFlavors {
development {
dimension "environment"
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
}
staging {
dimension "environment"
applicationIdSuffix ".staging"
versionNameSuffix "-staging"
}
production {
dimension "environment"
}
}
}
This example demonstrates the concept using Groovy syntax. Product flavors change the set of build variants, so scripts and commands must use the correct variant name. Configure separate identifiers only when the variants are intended to be installed as distinct applications.
6.4 Gradle Properties
Gradle properties influence build behavior. A project may use them for memory settings, feature flags, or other build configuration.
# Example properties; preserve project-specific defaults.
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m
android.useAndroidX=true
Do not copy arbitrary properties into an unfamiliar project. Confirm that the property is supported by the installed Gradle, Android Gradle Plugin, and React Native versions.
7. Configuring iOS Build Settings with Xcode
Xcode provides project settings, targets, schemes, build configurations, signing options, and build phases that determine how the iOS application is built and distributed.
7.1 Projects, Targets, and Schemes
- Project: Groups targets and shared project configuration.
- Target: Defines a product to build, such as the main app or an extension.
- Build configuration: Defines settings for a build mode, commonly Debug or Release.
- Scheme: Specifies which targets and actions are used for building, running, testing, profiling, and archiving.
7.2 Debug and Release Configurations
Debug configurations support development and debugging. Release configurations are generally intended for distribution and may use different optimization, signing, and compilation settings.
To inspect these settings:
- Open the iOS project or workspace in Xcode.
- Select the project in the navigator.
- Select the relevant application target.
- Open Build Settings.
- Review the selected configuration and the relevant build settings.
- Open Signing & Capabilities to inspect signing and enabled capabilities.
- Build and run the appropriate scheme to validate the changes.
7.3 Common iOS Build Settings
| Setting |
Purpose |
PRODUCT_BUNDLE_IDENTIFIER |
Defines the bundle identifier for a target. |
IPHONEOS_DEPLOYMENT_TARGET |
Specifies the minimum supported iOS version for the target. |
SWIFT_VERSION |
Configures the Swift language version where applicable. |
PRODUCT_NAME |
Defines the product name used during building. |
MARKETING_VERSION |
Commonly represents the user-facing application version. |
CURRENT_PROJECT_VERSION |
Commonly represents the build number. |
CODE_SIGN_STYLE |
Controls the signing style used by the target. |
DEVELOPMENT_TEAM |
Identifies the Apple development team used for signing where required. |
7.4 iOS Build Configurations for Environments
A project may use separate build configurations such as Debug, Release, Debug-Staging, and Release-Staging. A scheme can select the appropriate configuration for running, testing, or archiving the application.
When introducing new configurations, check dependency build settings, environment-variable mappings, CocoaPods integration, signing settings, and CI scripts. A configuration that builds locally may still fail in CI if it is not included in the build automation.
8. Managing Environment-Specific Configurations
Applications often need different settings for development, staging, and production. These settings may include API base URLs, feature flags, analytics identifiers, and service endpoints.
8.1 Common Environments
| Environment |
Purpose |
Example API |
| Development |
Supports active development and local testing. |
https://dev-api.example.com |
| Staging |
Supports pre-release verification against a test environment. |
https://staging-api.example.com |
| Production |
Serves real users and production data. |
https://api.example.com |
The domains are illustrative examples. Use the actual endpoints supplied by your backend team.
8.2 Example Environment Files
A project using a compatible environment-variable library may maintain separate files for each environment.
# .env.development
API_BASE_URL=https://dev-api.example.com
APP_ENV=development
# .env.staging
API_BASE_URL=https://staging-api.example.com
APP_ENV=staging
# .env.production
API_BASE_URL=https://api.example.com
APP_ENV=production
The exact file-loading mechanism depends on the library and build configuration. Environment files are not automatically loaded by React Native just because they exist in the project root.
8.3 Using Environment Variables in JavaScript
With a compatible library and its required Babel or native configuration, a project may expose selected values to JavaScript. The following is an illustrative example of the intended pattern.
// Example only: requires a configured environment-variable library.
import Config from "react-native-config";
const API_BASE_URL = Config.API_BASE_URL;
export async function fetchProfile() {
const response = await fetch(`${API_BASE_URL}/profile`);
if (!response.ok) {
throw new Error("Unable to load profile");
}
return response.json();
}
Do not assume the import or variable names work without installing and configuring the relevant package. Follow the installed library's instructions for both Android and iOS.
8.4 Important Environment Security Rules
- Do not place private backend credentials or secret signing keys in JavaScript environment variables.
- Values bundled into a mobile application can often be extracted by a determined person.
- Use environment variables for configuration, not as a security boundary.
- Keep server-side secrets on the server.
- Keep local secret files out of source control.
- Use different backend credentials and service access policies for each environment.
- Validate which environment is selected before creating a release build.
9. Configuring the Android Manifest and iOS Info.plist
Platform metadata files define or reference application properties, capabilities, and permission-related settings. These files must be updated carefully because malformed or conflicting configuration can prevent a build or cause runtime permission failures.
9.1 AndroidManifest.xml
The Android manifest declares important information about an Android application, including components, permissions, and selected application attributes.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="@string/app_name"
android:allowBackup="false">
<!-- Preserve the components and attributes required by your app. -->
</application>
</manifest>
This is a simplified illustration, not a complete manifest for a React Native application. Existing applications require additional components and attributes. Preserve required activities, application classes, theme references, and generated configuration.
9.2 Info.plist
Info.plist contains application metadata and configuration for iOS. Depending on the project and Xcode version, settings may be provided directly in the file, through build settings, or through generated configuration.
<key>CFBundleDisplayName</key>
<string>My React Native App</string>
<key>NSCameraUsageDescription</key>
<string>The camera is used to capture profile photos.</string>
Include privacy purpose strings only for capabilities the app actually uses. The wording should accurately explain the feature and the reason access is needed.
9.3 Configuration Best Practices
- Use the platform's expected format and key names.
- Avoid duplicate or conflicting values.
- Preserve existing React Native startup and native component declarations.
- Review changes after upgrading React Native or native dependencies.
- Test permission behavior on a device or simulator.
- Verify that generated files are not being overwritten by the build workflow.
10. Managing Permissions on Android and iOS
Permissions allow an application to access protected device resources. The required configuration differs by platform, and declaring a permission does not always mean that access will automatically be granted.
10.1 Android Permissions
Android permissions are commonly declared in AndroidManifest.xml. Some sensitive permissions also require runtime requests, depending on the permission and Android version.
<uses-permission android:name="android.permission.CAMERA" />
This declaration indicates that the application uses the camera capability. The app must still implement the appropriate permission flow and handle denial or restrictions.
10.2 iOS Privacy Usage Descriptions
iOS requires appropriate usage descriptions for many protected resources. For example, an application using the camera may need NSCameraUsageDescription in its effective Info.plist configuration.
10.3 Permission Comparison
| Feature |
Android Configuration |
iOS Configuration |
| Camera |
Camera permission declaration and appropriate runtime handling. |
Camera usage description and authorization handling. |
| Location |
Location permissions appropriate to the feature and OS version. |
Relevant location usage descriptions and authorization handling. |
| Microphone |
Record-audio permission and required runtime handling. |
Microphone usage description and authorization handling. |
| Notifications |
Notification permission behavior according to Android version and target SDK. |
Notification authorization request and capability configuration as applicable. |
| Photo library |
Media access or photo-picker APIs appropriate to the use case. |
Photo library permissions or picker APIs appropriate to the operation. |
10.4 Permission Management Best Practices
- Request permission when the user reaches a feature that needs it.
- Explain the benefit of granting permission.
- Handle denied, restricted, and unavailable states gracefully.
- Request only the access required for the feature.
- Test first-time requests and subsequent launches.
- Review platform policy and OS-version changes before release.
11. Managing Native Dependencies
React Native applications commonly use third-party packages that contain JavaScript code, native Android code, native iOS code, or a combination of these. Native dependencies require correct integration with the platform build systems.
11.1 JavaScript Dependencies
JavaScript packages are listed in package.json and installed using the package manager selected by the project.
npm install package-name
Use the actual package name required by your project. Review the package documentation for React Native compatibility, native setup steps, and any platform limitations.
11.2 Android Dependency Management
Many React Native libraries are integrated automatically, but native Android configuration may still be required. Android dependencies are commonly resolved through Gradle, and the project's Gradle Wrapper should be used for consistent builds.
cd android
./gradlew tasks
On Windows, the corresponding wrapper command is generally gradlew.bat. Use the tasks and build commands appropriate for the project's actual variants.
11.3 iOS Dependency Management with CocoaPods
Many React Native iOS projects use CocoaPods to install and integrate native dependencies. The Podfile describes the relevant dependencies and configuration.
cd ios
bundle exec pod install
This command is suitable when the project manages CocoaPods through Bundler and has the required Gemfile configuration. Otherwise, follow the repository's documented installation command. In many projects, the installed workspace should be opened in Xcode rather than opening only the project file.
11.4 Dependency Management Best Practices
- Use the package manager and lockfile already adopted by the project.
- Read installation instructions for each native library.
- Check compatibility with the installed React Native version.
- Review Android and iOS requirements separately.
- Do not remove lockfiles casually in an attempt to fix build errors.
- Rebuild native applications after changing native dependencies.
- Review release builds after adding a package that uses native code.
12. Configuring Android SDK and iOS Deployment Targets
Minimum OS settings determine which operating system versions an application supports. Compile-time SDK settings and target settings affect which APIs are available, which platform behavior applies, and whether dependencies can be built successfully.
12.1 Android SDK Settings
- minSdk: The minimum Android API level supported by the application.
- compileSdk: The Android API level used to compile the application.
- targetSdk: The Android API level that determines the platform behavior and compatibility expectations targeted by the application.
These settings have different purposes. A higher compile SDK does not automatically mean the application cannot run on older Android versions; minimum SDK and dependency compatibility are also important.
12.2 iOS Deployment Target
The iOS deployment target specifies the minimum iOS version supported by the native application target. It must be compatible with the React Native version and native dependencies in the project.
12.3 Choosing Supported Versions
- Review the minimum OS requirements of React Native itself.
- Check the minimum OS requirements of every important native dependency.
- Consider the operating system versions used by the intended audience.
- Test on the oldest supported OS version when possible.
- Do not raise minimum OS settings without understanding the effect on existing users.
- Keep platform settings consistent across app targets and related extensions where necessary.
13. Application Icons, Splash Screens, and Resources
Application icons, launch screens, fonts, and other assets often require platform-specific configuration. React Native can share many images and fonts at the JavaScript level, but launcher icons and native launch screens typically need native resources or supported configuration tooling.
13.1 Android Resources
Android resources commonly live under android/app/src/main/res/. Launcher icons may use density-specific resources or adaptive icon definitions, depending on the template and Android version.
13.2 iOS Assets
iOS applications commonly use an asset catalog such as Images.xcassets to manage application icons and image assets. The app target and asset catalog must be configured to use the correct icon set.
13.3 Splash Screen Configuration
A splash or launch screen provides a visual transition while the application starts. The implementation differs across platforms and may depend on whether the project uses bare React Native, Expo, or a dedicated splash-screen library.
13.4 Asset Best Practices
- Use platform-appropriate icon sizes and formats.
- Follow the current Android and Apple asset requirements.
- Verify that launch screens appear correctly in release builds.
- Test on multiple screen sizes and display densities.
- Avoid unnecessarily large image assets.
- Keep asset naming and source files organized.
14. Deep Linking and URL Schemes
Deep linking allows a URL or application link to open a particular screen or resource inside an application. It is useful for password-reset links, product pages, invitations, notifications, and navigation from other applications.
14.1 Android Deep Links
Android commonly configures deep links using intent filters in AndroidManifest.xml. Verified HTTPS App Links may also require domain association and additional configuration.
14.2 iOS URL Schemes and Universal Links
iOS supports custom URL schemes and Universal Links. Universal Links use an associated website domain and the appropriate application entitlement and server-side association file.
14.3 React Native Linking
React Native provides linking functionality that can be used to handle supported URLs from JavaScript. Native configuration must still be completed so that the operating system routes the link to the application.
14.4 Deep-Link Testing Checklist
- Test links when the application is not running.
- Test links when the application is already open.
- Validate malformed or unexpected URLs.
- Confirm that the intended screen opens.
- Verify Android intent filters and iOS associated-domain configuration.
- Test both development and release builds.
- Avoid exposing sensitive data in URL parameters.
15. Configuring Build Variants and Schemes
Build variants and schemes allow teams to produce multiple builds from the same source repository. They are useful for separating development, staging, and production environments, or for supporting distinct branded versions of an application.
15.1 Android Variants
An Android build variant is generally created by combining a build type with a product flavor. For example, a project with development and production flavors and debug and release build types can produce several variants.
# Example variant names:
developmentDebug
developmentRelease
productionDebug
productionRelease
15.2 iOS Schemes
Xcode schemes select the targets and build configurations used for actions such as running, testing, profiling, and archiving. Teams may create separate schemes for staging and production if the project requires distinct configuration.
15.3 Environment Mapping
When adding variants or schemes, ensure that the selected configuration points to the correct API endpoints, application identifiers, signing settings, and feature flags.
| Setting |
Development |
Staging |
Production |
| API endpoint |
Development server |
Staging server |
Production server |
| Debugging |
Enabled as appropriate |
Controlled for testing |
Configured for release |
| Application identifier |
May use a development suffix |
May use a staging suffix |
Stable store identifier |
| Signing |
Development signing |
Internal or test distribution signing |
Release distribution signing |
| Analytics |
Development project |
Test project or controlled configuration |
Production project |
16. Android Application Signing
Android application signing verifies the identity associated with a built application. A release build must be configured according to the intended distribution channel. For Google Play, applications are commonly uploaded as Android App Bundles, with Play App Signing configured as required.
16.1 Debug and Release Signing
Android tooling generally uses a debug signing key for local development. Release distribution requires the appropriate signing configuration and secure management of the associated credentials.
16.2 Signing Configuration Example
// Simplified Groovy example only.
// Store signing values outside committed source files.
android {
signingConfigs {
release {
if (project.hasProperty("MYAPP_UPLOAD_STORE_FILE")) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
This example must be adapted to the actual Gradle file and project requirements. Do not commit passwords or private keystore material to source control. A production pipeline should fail safely if required signing configuration is missing rather than accidentally producing an incorrectly signed release.
16.3 Android Release Build Commands
# From the project root, create a release APK:
cd android
./gradlew :app:assembleRelease
# Create a release Android App Bundle:
./gradlew :app:bundleRelease
Use the wrapper scripts and variant names appropriate to the project. The resulting artifact location depends on the selected variant and build task.
17. iOS Code Signing and Provisioning
iOS code signing associates an application build with a signing identity and the appropriate provisioning configuration. Signing is required for many device and distribution workflows.
17.1 Important Signing Components
- Bundle identifier: Identifies the application target.
- Apple development team: Identifies the team associated with the app's signing configuration.
- Signing certificate: Represents the signing identity used for the build.
- Provisioning profile: Connects signing identity, app identifier, and relevant distribution or device authorization information as applicable.
- Entitlements: Declare capabilities and permissions associated with the application.
17.2 Automatic and Manual Signing
Xcode supports automatic signing, which can simplify development by managing certain signing tasks, and manual signing, which allows more explicit control. The correct choice depends on team workflow, distribution requirements, CI configuration, and the capabilities used by the app.
17.3 Signing Checklist
- Confirm that the correct Xcode target is selected.
- Verify the bundle identifier.
- Choose the appropriate Apple development team.
- Confirm the signing certificate and provisioning setup.
- Check entitlements for push notifications, associated domains, or other capabilities.
- Verify that required credentials are available in the build environment.
- Test archive and distribution steps before a planned release.
18. Managing React Native Configuration with Expo
Some React Native applications use Expo and its app configuration system. Expo projects may define settings in app.json or a dynamic app.config.js or app.config.ts file. The configuration can include platform-specific identifiers, icons, permissions, and other build properties supported by Expo.
18.1 Example app.json
{
"expo": {
"name": "My React Native App",
"slug": "my-react-native-app",
"version": "1.0.0",
"ios": {
"bundleIdentifier": "com.example.myapp"
},
"android": {
"package": "com.example.myapp"
}
}
}
This is a simplified example for an Expo project. Check the schema supported by the installed Expo SDK. A bare React Native project does not automatically use every Expo configuration property, and native project files may still need to be managed directly.
18.2 Static and Dynamic Configuration
- Static configuration: Stores fixed project values in app.json.
- Dynamic configuration: Uses JavaScript or TypeScript to compute configuration values when the project configuration is evaluated.
- Native configuration: Settings may also live in Android and iOS project files.
18.3 Config Plugins
In supported Expo workflows, config plugins can modify native project configuration during prebuild. This can reduce manual edits, but the plugin must support the intended SDK and native settings. Review generated changes and test the resulting native projects.
19. Native Configuration and the React Native New Architecture
React Native's native integration architecture has evolved. Newer projects may use the New Architecture, while existing projects may retain older integration patterns or migrate gradually. Configuration needs can differ according to the React Native version and the native libraries being used.
19.1 Important Concepts
- Hermes: A JavaScript engine commonly used by React Native.
- Codegen: Generates native code based on supported specifications in relevant React Native integrations.
- TurboModules: A native module system associated with the New Architecture.
- Fabric: The New Architecture's rendering system.
- Native dependencies: Libraries that may require platform-specific build integration.
19.2 Configuration Best Practices
- Use documentation that matches the installed React Native version.
- Check whether the library supports the project's architecture configuration.
- Avoid copying native setup steps from unrelated versions.
- Regenerate or rebuild native artifacts when required by the workflow.
- Verify that Android and iOS builds both succeed after architectural changes.
20. Cleaning, Rebuilding, and Troubleshooting Projects
Configuration changes can leave stale build artifacts or expose incompatibilities between dependencies. Cleaning and rebuilding may help, but developers should first identify the underlying error instead of deleting files indiscriminately.
20.1 Android Troubleshooting Commands
cd android
./gradlew clean
./gradlew :app:assembleDebug
The clean task removes supported Gradle build outputs. If the build still fails, inspect the first meaningful error in the Gradle output and confirm that the installed Java, Gradle, Android Gradle Plugin, SDK, and React Native versions are compatible.
20.2 iOS Dependency and Build Troubleshooting
# Run from the project root when the project uses CocoaPods:
cd ios
pod install
If the repository uses Bundler, follow the project's documented bundle exec pod install command. After dependency changes, open the appropriate Xcode workspace and build the intended scheme. Avoid deleting lockfiles or changing multiple tool versions without understanding the effect.
20.3 Common Configuration Problems
| Problem |
Possible Cause |
Suggested Solution |
| Android build fails after a dependency update. |
Incompatible Gradle, SDK, Java, or native package versions. |
Review the error and verify compatibility against the project version. |
| iOS pods fail to install. |
Dependency resolution, Ruby tooling, CocoaPods, or deployment-target mismatch. |
Follow the repository's installation instructions and inspect the first dependency error. |
| Wrong app name appears on Android. |
Manifest label or string resource is configured incorrectly. |
Check the effective application label and string resources. |
| Wrong app name appears on iOS. |
Display name or target build settings contain another value. |
Check CFBundleDisplayName and related Xcode settings. |
| Release build uses a test API. |
Incorrect environment mapping or release configuration. |
Inspect the selected build variant, scheme, and bundled configuration. |
| Camera permission fails. |
Missing platform declaration or runtime authorization handling. |
Verify the relevant manifest, usage description, and permission flow. |
| Application fails to install as an update. |
Identifier or signing mismatch, or invalid version progression. |
Check application identifiers, signing identity, and version fields. |
| Native library is not found. |
Dependency was not installed or native project integration is incomplete. |
Review package instructions and reinstall dependencies using the correct workflow. |
| iOS build works locally but fails in CI. |
Missing credentials, scheme, configuration, environment values, or toolchain setup. |
Compare local and CI build settings and verify all required inputs. |
| Environment values are undefined. |
Environment library is not configured for the selected platform or variant. |
Verify installation, build-time file selection, and variable naming. |
21. Configuration Management with Git
Git helps teams track native configuration changes, review them, and restore earlier versions when necessary. Because Android and iOS configuration can affect the entire application, native project changes should be reviewed just as carefully as JavaScript changes.
21.1 Files Commonly Tracked
- Native source files and project settings required to build the application.
- Gradle configuration and wrapper files.
- Podfile and relevant lockfiles.
- Xcode project and shared scheme configuration.
- App configuration and environment templates.
- Required non-secret assets and resource files.
21.2 Files Commonly Excluded
- Private signing credentials and keystores.
- Local environment files containing secrets.
- Machine-specific build outputs.
- Temporary files generated by editors and build tools.
The exact .gitignore rules depend on the project. Do not ignore every native project file or every generated file without understanding which files are required by the build and team workflow.
21.3 Example Environment Template
# .env.example
API_BASE_URL=
APP_ENV=development
A template documents required variables without including private values. Team members can create their local environment file from this template and supply the correct values through the approved process.
21.4 Review Configuration Changes
- Review the diff before committing native configuration changes.
- Confirm that secrets are not included.
- Build Android and iOS after changing shared configuration.
- Verify the correct environment and application identifiers.
- Document any new setup steps.
- Use a focused commit so changes are easier to review and revert.
22. Continuous Integration and Automated Builds
Continuous integration (CI) automates tasks such as installing dependencies, running tests, building applications, and validating release configuration. A reliable CI pipeline helps teams detect configuration errors before they reach users.
22.1 Common CI Steps
- Check out the repository.
- Install the required Node.js version and package manager.
- Install dependencies using the project's lockfile.
- Run linting and automated tests.
- Install native dependencies for the target platform.
- Configure environment variables and secure signing credentials.
- Build the intended Android variant or iOS scheme.
- Store the generated artifacts securely.
- Run any additional validation required before distribution.
22.2 CI Security
- Store signing credentials in the CI platform's secure secret store.
- Do not print secrets in build logs.
- Limit access to release credentials.
- Separate test credentials from production credentials.
- Require appropriate approvals for production releases.
- Rotate credentials when exposure is suspected or required by policy.
23. Mini Project: Development, Staging, and Production Configuration
Build a sample React Native application with separate development, staging, and production configurations. The goal is to ensure that each build uses the correct API endpoint and application identity without mixing test and production settings.
23.1 Project Requirements
- Use separate API endpoints for development, staging, and production.
- Define the correct application name and identifier for each required variant.
- Configure Android build variants where needed.
- Configure iOS schemes or build configurations where needed.
- Keep private values out of source control.
- Verify that release builds use production configuration.
- Document how another developer can build each environment.
23.2 Example Environment Mapping
const environments = {
development: {
apiBaseUrl: "https://dev-api.example.com"
},
staging: {
apiBaseUrl: "https://staging-api.example.com"
},
production: {
apiBaseUrl: "https://api.example.com"
}
};
export default environments;
This is a simple illustration of configuration mapping, not a secure secret store. A real project should connect the selected environment to its build configuration and avoid accidentally shipping test endpoints in production.
23.3 Testing the Project
- Build and launch the development variant.
- Verify that requests use the development API endpoint.
- Build and launch the staging variant.
- Verify the staging application identity and endpoint.
- Create a production build using the intended release configuration.
- Inspect the effective configuration and confirm the production endpoint.
- Check signing and version settings before distributing the release artifact.
- Record the commands and configuration steps in the project documentation.
24. Best Practices for Managing Android and iOS Configurations
24.1 Consistency
- Keep the application name, identifiers, and versioning strategy documented.
- Ensure that shared application features behave consistently on both platforms.
- Use platform-specific configuration where platform behavior genuinely differs.
- Review the Android and iOS requirements whenever a native dependency is added.
24.2 Maintainability
- Prefer small, clearly explained configuration changes.
- Avoid hardcoding environment-specific settings in multiple files.
- Document non-obvious build settings and custom scripts.
- Use the project's existing dependency and build conventions.
- Keep native project templates and documentation aligned with the installed React Native version.
24.3 Reliability
- Build both platforms regularly, even when changes appear JavaScript-only.
- Test Debug and Release configurations.
- Validate permissions, deep links, and notifications on each platform.
- Check build artifacts before release.
- Use CI to detect missing configuration and dependency issues.
24.4 Security
- Never commit private signing credentials.
- Do not treat mobile environment variables as secrets.
- Use secure storage for credentials where appropriate.
- Limit application permissions to what is required.
- Keep production signing access restricted.
- Verify environment selection before publishing an app.
25. Interview Questions and Answers
Q1. What is project configuration in React Native?
Answer: Project configuration defines the settings required to build, run, test, and distribute a React Native application, including platform identifiers, build settings, permissions, dependencies, environment variables, and signing.
Q2. What is the difference between Android and iOS configuration?
Answer: Android uses tools such as Gradle and AndroidManifest.xml, while iOS uses Xcode project settings, schemes, build configurations, and Info.plist or equivalent configuration. Each platform also has its own signing and release workflow.
Q3. What is an Android application ID?
Answer: It is the identifier used by Android and distribution services to identify an installed application. It is commonly configured through the app-level Gradle file.
Q4. What is an iOS bundle identifier?
Answer: It identifies the iOS application target and is used in Apple's development and distribution ecosystem.
Q5. What is Gradle?
Answer: Gradle is a build automation system used by Android projects to configure dependencies, build variants, compilation, packaging, and other build tasks.
Q6. What is the purpose of Xcode build configurations?
Answer: Build configurations define settings for different build modes, commonly Debug and Release. They can also be customized for additional environments.
Q7. What is the difference between Android versionCode and versionName?
Answer: versionCode is an integer used for release progression, while versionName is a user-facing version string.
Q8. What are iOS marketing version and build number?
Answer: The marketing version communicates the release version, while the build number identifies a particular build. They are commonly represented by MARKETING_VERSION and CURRENT_PROJECT_VERSION in Xcode.
Q9. What are environment-specific configurations?
Answer: They are settings that differ between environments, such as API endpoints, analytics configuration, or feature flags for development, staging, and production.
Q10. Are environment variables in a mobile application secret?
Answer: No. Values bundled into an application can often be extracted. Private server credentials should remain on the server or in an appropriate secure system.
Q11. What is AndroidManifest.xml?
Answer: It is a native Android configuration file that declares important application metadata, components, permissions, and related attributes.
Q12. What is Info.plist?
Answer: Info.plist contains iOS application metadata and configuration, including certain privacy usage descriptions and app properties.
Q13. What is a product flavor in Android?
Answer: A product flavor defines a variant of an Android application, often used to create development, staging, production, or branded builds.
Q14. What is an Xcode scheme?
Answer: An Xcode scheme defines the targets and build configurations used for actions such as running, testing, profiling, and archiving an application.
Q15. Why does a React Native project use CocoaPods?
Answer: Many React Native iOS projects use CocoaPods to resolve and integrate native iOS dependencies into the Xcode workspace.
Q16. What is code signing?
Answer: Code signing associates an application build with a signing identity and the appropriate authorization or distribution configuration.
Q17. Why should private signing credentials not be committed to Git?
Answer: Anyone who obtains private signing credentials may be able to misuse them. Credentials should be protected using secure storage and restricted access.
Q18. What is the difference between minSdk and targetSdk?
Answer: minSdk defines the minimum Android version supported by the application, while targetSdk indicates the Android API level whose behavior and compatibility requirements the application targets.
Q19. Why should Android and iOS both be built after native dependency changes?
Answer: A dependency may integrate differently on each platform. Building both platforms helps reveal missing setup, incompatible APIs, and platform-specific errors.
Q20. How can configuration problems be reduced in a team?
Answer: Use documented build steps, consistent lockfiles, environment templates, version-controlled native settings, secure credentials, automated builds, and regular testing on both platforms.
26. Practice Exercises
- Identify the major Android and iOS configuration files in an existing React Native project.
- Change the display name of an application on Android and iOS.
- Find the Android application ID and iOS bundle identifier.
- Update version numbers for a sample release.
- Compare the Android minimum SDK and iOS deployment target settings.
- Inspect the Android manifest and identify the permissions currently declared.
- Inspect the iOS privacy usage descriptions and explain why each one is needed.
- Create development, staging, and production environment templates.
- Configure Android product flavors in a sample project.
- Create an additional Xcode build configuration and scheme.
- Install a native React Native dependency and follow its Android and iOS setup steps.
- Build a debug APK and a release Android App Bundle.
- Inspect iOS signing settings and verify the selected bundle identifier.
- Test a deep link on Android and iOS.
- Review a Git diff and remove any accidental secret values before committing.
- Write a setup guide that allows a new developer to build both platforms.
27. Quick Revision Checklist
- Understand the React Native project structure.
- Know the difference between Android and iOS native configuration.
- Identify the role of Gradle, AndroidManifest.xml, Xcode, and Info.plist.
- Configure application names and identifiers correctly.
- Manage Android versionCode and versionName.
- Manage iOS marketing version and build number.
- Understand Android build types and product flavors.
- Understand iOS schemes and build configurations.
- Configure development, staging, and production environments.
- Understand how native dependencies are integrated.
- Configure permissions and privacy usage descriptions.
- Understand Android and iOS signing requirements.
- Keep private credentials out of source control.
- Test both platforms after native configuration changes.
- Use documented and repeatable build processes.
28. Recommended Learning Resources
29. Conclusion
Managing Android and iOS project configurations is an essential skill for React Native developers. Although JavaScript and TypeScript can power shared application logic, the native projects determine how the app is built, identified, signed, configured, and distributed on each platform.
By understanding Gradle, Android manifests, Xcode build settings, schemes, environment variables, permissions, native dependencies, signing, and release builds, developers can maintain more reliable cross-platform applications. Careful configuration management also reduces environment mix-ups, dependency problems, security risks, and unexpected release failures.
Practice by making small configuration changes, building both platforms regularly, documenting the setup process, and testing the exact variants intended for distribution. Always consult documentation that matches your installed React Native version and native toolchain.